// pages/paint/paint.js
const app = getApp()
const dayjs = require('dayjs')

Page({
  data: {
    roomId: null,
    players: new Array(6),
    currentIndex: 0,
    canvas: null,
    pointList: [],
    paintWatcher: null,
    word: {
      value: '嘟嘟',
      tips: '露露'
    },
    countdown: 60,
    timer: null,
    roomWatcher: ''
  },
  onLoad(options) {
    const roomId = options.roomId
    this.setData({
      roomId
    })
    // this.getRoomInfo(roomId)
    this.getCanvas()
    this.initWatchRoom(roomId)
  },
  onUnload() {
    this.data.paintWatcher && this.data.paintWatcher.close()
    this.data.roomWatcher && this.data.roomWatcher.close()
    this.data.timer && clearInterval(this.data.timer)
  },
  // getRoomInfo (roomId) {
  //   wx.cloud.callFunction({
  //     name: 'drawsthFunctions',
  //     data: {
  //       url: 'room/getInfo',
  //       data: {
  //         roomId
  //       }
  //     }
  //   }).then(res => {
  //     const players = [...res.result.data.players]
  //     const currentIndex = res.result.data.painterIndex
  //     this.setData({
  //       players
  //     }, () => {
  //       const index = this.data.players.findIndex(item => item.openid === app.globalData.userInfo.openid)
  //       if (index === currentIndex) {
  //         this.updatePainter()
  //       }
  //     })
  //   })
  // },
  updatePainter(updatePainterIndex = false) {
    wx.cloud.callFunction({
      name: 'drawsthFunctions',
      data: {
        url: 'room/updateInfo',
        data: {
          roomId: this.data.roomId,
          updatePainterIndex
        }
      }
    })
  },
  setCountdown() {
    this.data.timer && clearInterval(this.data.timer)
    const timer = setInterval(() => {
      const countdown = this.data.countdown - 1
      this.setData({
        countdown
      })
      if (countdown === 0) {
        clearInterval(timer)
        wx.showToast({
          title: '时间到',
          icon: 'none',
          duration: 1500,
          mask: true
        })
        setTimeout(() => {
          if (this.data.currentIndex === this.data.players.length - 1) {
            wx.showToast({
              title: '游戏结束',
              icon: 'none',
              duration: 1500,
              mask: true
            })
            this.updateRoomStatus()
          } else {
            const index = this.data.players.findIndex(item => item.openid === app.globalData.userInfo.openid)
            if (index === this.data.currentIndex) {
              this.updatePainter(true)
            }
            this.draw([])
          }
        }, 1500)
      }
    }, 1000)
    this.setData({
      timer
    })
  },
  updateRoomStatus() {
    const index = this.data.players.findIndex(item => item.openid === app.globalData.userInfo.openid)
    if (index !== this.data.currentIndex) return
    wx.cloud.callFunction({
      name: 'drawsthFunctions',
      data: {
        url: 'room/updateInfo',
        data: {
          roomId: this.data.roomId,
          status: 3
        }
      }
    }).then(() => {
      this.data.paintWatcher && this.data.paintWatcher.close()
      this.data.roomWatcher && this.data.roomWatcher.close()
      this.data.timer && clearInterval(this.data.timer)
    })
  },
  getCanvas() {
    wx.createSelectorQuery()
      .select('#paint-canvas')
      .fields({
        node: true,
        size: true,
      })
      .exec((res) => {
        const width = res[0].width
        const height = res[0].height
        const canvas = res[0].node
        const ctx = canvas.getContext('2d')
        const dpr = wx.getSystemInfoSync().pixelRatio
        canvas.width = width * dpr
        canvas.height = height * dpr
        ctx.scale(dpr, dpr)
        this.setData({
          canvas
        })
      })
  },
  onTouchStart(event) {
    const index = this.data.players.findIndex(item => item.openid === app.globalData.userInfo.openid)
    if (index !== this.data.currentIndex) {
      return
    }
    const position = event.touches[0]
    const { x, y } = position
    this.setData({
      pointList: [{ x, y }]
    })
    const ctx = this.data.canvas.getContext('2d')
    ctx.beginPath()
    ctx.lineWidth = '3'
    ctx.strokeStyle = '#f22'
    ctx.moveTo(x, y)
  },
  onTouchMove(event) {
    const index = this.data.players.findIndex(item => item.openid === app.globalData.userInfo.openid)
    if (index !== this.data.currentIndex) {
      return
    }
    const position = event.touches[0]
    const { x, y } = position
    const pointList = [...this.data.pointList]
    pointList.push({ x, y })
    this.setData({
      pointList
    })
    const ctx = this.data.canvas.getContext('2d')
    ctx.lineTo(x, y)
    ctx.stroke()
  },
  onTouchEnd() {
    const index = this.data.players.findIndex(item => item.openid === app.globalData.userInfo.openid)
    if (index !== this.data.currentIndex) {
      return
    }
    const { roomId, pointList: points } = this.data
    wx.cloud.callFunction({
      name: 'drawsthFunctions',
      data: {
        url: 'point/add',
        data: {
          roomId,
          points
        }
      }
    })
  },
  initPainter(roomId) {
    wx.cloud.callFunction({
      name: 'drawsthFunctions',
      data: {
        url: 'point/getList',
        data: {
          roomId
        }
      }
    }).then(res => {
      if (res.result.data.length) {
        res.result.data.forEach(item => {
          this.draw(item.points)
        })
      }
    })
  },
  initWatchPaint(roomId) {
    const db = wx.cloud.database()
    this.paintWatcher = db.collection('point').where({
      roomId
    }).watch({
      onChange: (snapshot) => {
        // console.log('snapshot', snapshot)
        // const index = this.data.players.findIndex(item => item.openid === app.globalData.userInfo.openid)
        // if (index === this.data.currentIndex) {
        //   return
        // }
        if (snapshot.type === 'init') {
          // const allPointList = [...snapshot.docs]
          const pointsList = snapshot.docs.filter(item => item.playerId === this.data.players[this.data.currentIndex].openid)
          pointsList.forEach(item => {
            this.draw(item.points)
          })
        } else {
          const currentPointObj = snapshot.docChanges[0].doc
          const pointList = currentPointObj.points
          this.draw(pointList)
        }
      },
      onError: (err) => {
        console.error('the watch closed because of error', err)
      }
    })
  },
  draw(pointList) {
    const ctx = this.data.canvas.getContext('2d')
    if (pointList.length) {
      ctx.beginPath()
      ctx.lineWidth = '3'
      ctx.strokeStyle = '#f22'
      ctx.moveTo(pointList[0].x, pointList[0].y)
      for (let i = 1; i < pointList.length; i++) {
        ctx.lineTo(pointList[i].x, pointList[i].y)
      }
      ctx.stroke()
    } else {
      const { width, height } = this.data.canvas
      ctx.clearRect(0, 0, width, height)
    }
  },
  initWatchRoom(roomId) {
    const db = wx.cloud.database()
    const roomWatcher = db.collection('room').doc(roomId).watch({
      onChange: (snapshot) => {
        // console.log('room', snapshot.type, snapshot)
        // console.log('docs\'s changed events', snapshot.docChanges)
        // console.log('query result snapshot after the event', snapshot.docs)
        // console.log('is init data', snapshot.type === 'init')
        const roomInfo = snapshot.docs[0]
        if (roomInfo.status === 3) return
        if (snapshot.type === 'init') {
          const players = [...roomInfo.players]
          const currentIndex = roomInfo.painterIndex
          this.setData({
            players
          }, () => {
            const index = this.data.players.findIndex(item => item.openid === app.globalData.userInfo.openid)
            if (index === currentIndex) {
              this.updatePainter(false)
            }
            this.initWatchPaint(roomId)
          })
          
        }
        const currentIndex = roomInfo.painterIndex
        const diffTime = dayjs().diff(roomInfo.updateTime, 's')
        const countdown = 60 - diffTime
        if (countdown <= 0) return
        this.setData({
          currentIndex,
          countdown
        }, () => {
          this.setCountdown()
        })
      },
      onError: (err) => {
        console.error('the watch closed because of error', err)
      }
    })
    this.setData({
      roomWatcher
    })
  }
})